<?php

/**
 * 执行异步任务Task
 * Class TcpServer
 */
class TcpServer {

    CONST HOST = "127.0.0.1";
    CONST PORT = 9501;

    public $ws = null;

    public function __construct() {
        $this->ws = new Swoole\Server(self::HOST, self::PORT);

        $this->ws->set(
            [
                'worker_num'       => 2, //指定启动的worker进程数, 设置为CPU的1-4倍最合理
                'max_request'      => 10000, //每个worker进程允许处理的最大任务数
                'task_worker_num'  => 4, //服务器开启的task进程数
                'task_max_request' => 1000, //每个task进程允许处理的最大任务数
                'daemonize'        => false, //守护进程(true/false)

                'open_eof_check'   => true, //打开EOF检测, 每次包以EOF结尾，才send给服务端
                //'open_eof_split'   => true, //自动分包, 比较消耗cpu资源
                'package_eof'      => "\r\n", //设置EOF后缀，一般为"\r\n"
            ]
        );

        $this->ws->on("start", [$this, 'onStart']);
        $this->ws->on("workerStart", [$this, 'onWorkerStart']);
        $this->ws->on("receive", [$this, 'onReceive']);
        $this->ws->on("task", [$this, 'onTask']);
        $this->ws->on("finish", [$this, 'onFinish']);

        $this->ws->start();
    }

    /**
     * @param $server
     */
    public function onStart($server) {
        echo '[' . date('Y-m-d H:i:s') . ']' . "onStart" . PHP_EOL;
    }

    /**
     * @param $server
     * @param $worker_id
     * @throws Exception
     */
    public function onWorkerStart($server, $worker_id) {
        echo '[' . date('Y-m-d H:i:s') . ']' . "onWorkerStart" . PHP_EOL;

        // 定义应用目录
        define('DS', DIRECTORY_SEPARATOR);
        define('ROOT', realpath('../') . DS);
        define('APP', ROOT . 'app');
        define('APP_MODULE', 'app');
        define('CORE', ROOT . 'core');

        // 自定义加载器
        require CORE . '/Base.php';

        spl_autoload_register('\core\Base::load');
        \core\Base::run();
    }

    public function onReceive($server, $fd, $reactorId, $data) {
        echo '[' . date('Y-m-d H:i:s') . ']' . "onReceive: " . $data . PHP_EOL;
        $this->ws->task($data);
    }

    /**
     * onTask 回调函数 SwooleTask 进程池内被异步执行。执行完成后调用 $serv->finish() 返回结果
     * @param $server
     * @param $taskId
     * @param $workerId
     * @param $data
     * @return bool
     */
    public function onTask($server, $taskId, $workerId, $data) {
        echo '[' . date('Y-m-d H:i:s') . ']' . "onTask" . PHP_EOL;
        $param = json_decode($data, true);

        // 分发 task 任务机制，让不同的任务 走不同的逻辑
        $method = $param['method'];
        $flag = app\common\lib\SwooleTask::getInstance()->$method($param['data'], $server);

        app\common\lib\Helper::debugLog("$data result: {$flag}", 'task');
        echo '[' . date('Y-m-d H:i:s') . ']' . "onTask-{$method}: {$flag}" . PHP_EOL;

        //返回任务执行的结果给worker
        return $flag;
    }

    /**
     * 处理异步任务的结果(此回调函数在worker进程中执行)
     * @param $server
     * @param $taskId
     * @param $data
     */
    public function onFinish($server, $taskId, $data) {
        echo '[' . date('Y-m-d H:i:s') . ']' . "onFinish - {$taskId}: {$data}" . PHP_EOL;
    }
}

// nohup php /data/www/xxx/server/TcpServer.php > /data/www/xxx/runtime/log/tcp.log &
new TcpServer();